package com.jacky.iot.resources;

import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.elements.util.Bytes;

public class CreateResource extends CoapResource {

    private byte[] data = null;
    private int dataCf = MediaTypeRegistry.UNDEFINED;

    public CreateResource(String name) {
        super(name);
        getAttributes().setTitle("Resource which does not exist yet (to perform atomic PUT)");
        setVisible(false);
    }

    @Override
    public void handlePUT(CoapExchange exchange) {
        if (data != null && exchange.getRequestOptions().hasIfNoneMatch()) {
            exchange.respond(CoAP.ResponseCode.PRECONDITION_FAILED);
            data = null;
        } else {
            if (exchange.getRequestOptions().hasContentFormat()) {
                storeData(exchange.getRequestPayload(), exchange.getRequestOptions().getContentFormat());
                exchange.respond(CoAP.ResponseCode.CREATED);
            } else {
                exchange.respond(CoAP.ResponseCode.BAD_REQUEST, "Content-Format not set");
            }
        }
    }

    @Override
    public void handleGET(CoapExchange exchange) {
        if (data != null) {
            exchange.respond(CoAP.ResponseCode.CONTENT, data, dataCf);
        } else {
            exchange.respond(CoAP.ResponseCode.NOT_FOUND);
        }
    }

    @Override
    public void handleDELETE(CoapExchange exchange) {
        data = null;
        setVisible(false);
        exchange.respond(CoAP.ResponseCode.DELETED);
    }

    private synchronized void storeData(byte[] payload, int contentFormat) {
        data = payload != null ? payload : Bytes.EMPTY;
        dataCf = contentFormat;
        getAttributes().clearContentType();
        getAttributes().addContentType(dataCf);
        getAttributes().setMaximumSizeEstimate(data.length);

        setVisible(true);

        changed();
    }
}
